﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace Maydew.Windows.Forms.Controls.FlexiCell
{
    /// <summary>
    /// 具有边框、编辑器的单元格。
    /// </summary>
    public class Cell : Shape
    {
        #region " 事件 "
        /// <summary>
        /// 显示文本时发生。
        /// </summary>
        public event EventHandler DisplayText;
        /// <summary>
        /// Value属性值改变后发生。
        /// </summary>
        public event EventHandler ValueChanged;
        /// <summary>
        /// Value属性值改变时发生。
        /// </summary>
        public event EventHandler ValueChanging;
        /// <summary>
        /// Text属性值改变后发生。
        /// </summary>
        public event EventHandler TextChanged;
        /// <summary>
        /// Text属性值改变时发生。
        /// </summary>
        public event EventHandler TextChanging;
        /// <summary>
        /// RowIndex属性值改变后发生。
        /// </summary>
        public event RowIndexChangedEventHander RowIndexChanged;
        /// <summary>
        /// ColumnName属性值改变后发生。
        /// </summary>
        public event ColumnNameChangedEventHandler ColumnNameChanged;
        /// <summary>
        /// Editing属性值改变后发生。
        /// </summary>
        public event EventHandler EditingChanged;
        #endregion

        #region " 私有字段 "
        /// <summary>
        /// 获取或设置单元格编辑器。
        /// </summary>
        private CellEditor _editor;
        /// <summary>
        /// 获取或设置附加数据。
        /// </summary>
        private object _tag;
        /// <summary>
        /// 获取或设置文本。
        /// </summary>
        private string _text;
        /// <summary>
        /// 获取或设置单元格值。
        /// </summary>
        private object _value;
        /// <summary>
        /// 获取或设置行号。
        /// </summary>
        private int _rowIndex;
        /// <summary>
        /// 获取或设置列名。
        /// </summary>
        private string _columnName;
        /// <summary>
        /// 获取或设置单元格具有焦点。
        /// </summary>
        private bool _focused;
        /// <summary>
        /// 获取或设置文本对齐样式。
        /// </summary>
        private ContentAlignment _textAlign;
        /// <summary>
        /// 获取或设置字体。
        /// </summary>
        private Font _font;
        /// <summary>
        /// 获取单元格是否合并。
        /// </summary>
        private bool _merged;
        /// <summary>
        /// 获取合并后的单元格集合。
        /// </summary>
        private List<Cell> _mergedCells;
        /// <summary>
        /// 获取合并后的主单元格。
        /// </summary>
        private Cell _mainCell;
        /// <summary>
        /// 获取或设置左边框样式。
        /// </summary>
        private CellBorderStyle _leftBorderStyle;
        /// <summary>
        /// 获取或设置上边框样式。
        /// </summary>
        private CellBorderStyle _topBorderStyle;
        /// <summary>
        /// 获取或设置右边框样式。
        /// </summary>
        private CellBorderStyle _rightBorderStyle;
        /// <summary>
        /// 获取或设置下边框样式。
        /// </summary>
        private CellBorderStyle _bottomBorderStyle;
        /// <summary>
        /// 获取或设置是否编辑中。
        /// </summary>
        private bool _editing;
        /// <summary>
        /// 获取或设置背景颜色。
        /// </summary>
        private Color _backColor;
        /// <summary>
        /// 获取或设置前景颜色。
        /// </summary>
        private Color _foreColor;
        /// <summary>
        /// 获取或设置格式化信息。
        /// </summary>
        private string _format;
        #endregion

        #region " 构造函数 "
        /// <summary>
        /// 初始化 Cell 类的新实例。
        /// </summary>
        public Cell()
        {
            _leftBorderStyle = new CellBorderStyle();
            _leftBorderStyle.PropertyChanged += new EventHandler(_borderStyle_PropertyChanged);
            _topBorderStyle = new CellBorderStyle();
            _topBorderStyle.PropertyChanged += new EventHandler(_borderStyle_PropertyChanged);
            _rightBorderStyle = new CellBorderStyle();
            _rightBorderStyle.PropertyChanged += new EventHandler(_borderStyle_PropertyChanged);
            _bottomBorderStyle = new CellBorderStyle();
            _bottomBorderStyle.PropertyChanged += new EventHandler(_borderStyle_PropertyChanged);
            //_font = SystemFonts.CaptionFont;
            _textAlign = ContentAlignment.MiddleCenter;
            _mergedCells = new List<Cell>();
            _backColor = Color.White;
            _foreColor = Color.Black;
        }
        #endregion

        #region " 属性 "
        /// <summary>
        /// 获取或设置单元格编辑器。
        /// </summary>
        public CellEditor Editor
        {
            get
            {
                if (_editor == null) Editor = new TextCellEditor();
                return _editor;
            }
            set
            {
                if (_editor != value)
                {
                    if (_editor != null) _editor.Dispose();
                    _editor = value;
                    if (_editor != null)
                    {
                        _editor.Owner = this;
                    }
                }
            }
        }
        /// <summary>
        /// 获取或设置文本。
        /// </summary>
        public string Text
        {
            get
            {
                return _text;
            }
            set
            {
                if (_text != value)
                {
                    OnTextChanging(EventArgs.Empty);
                    _text = value;
                    OnTextChanged(EventArgs.Empty);
                }
            }
        }
        /// <summary>
        /// 获取或设置附加数据。
        /// </summary>
        public object Tag
        {
            get
            {
                return _tag;
            }
            set
            {
                _tag = value;
            }
        }
        /// <summary>
        /// 获取或设置单元格值。
        /// </summary>
        public object Value
        {
            get
            {
                return _value;
            }
            set
            {
                if (_value != value)
                {
                    OnValueChanging(EventArgs.Empty);
                    _value = value;
                    OnValueChanged(EventArgs.Empty);
                    OnDisplayText(EventArgs.Empty);
                }
            }
        }
        /// <summary>
        /// 获取或设置行号。
        /// </summary>
        public int RowIndex
        {
            get { return _rowIndex; }
            set
            {
                if (_rowIndex != value)
                {
                    RowIndexChangedEventArgs e = new RowIndexChangedEventArgs(_rowIndex, value);
                    _rowIndex = value;
                    OnRowIndexChanged(e);
                }
            }
        }
        /// <summary>
        /// 获取或设置列名。
        /// </summary>
        public string ColumnName
        {
            get { return _columnName; }
            set
            {
                if (string.Compare(_columnName, value) != 0)
                {
                    ColumnNameChangedEventArgs e = new ColumnNameChangedEventArgs(_columnName, value);
                    _columnName = value;
                    OnColumnNameChanged(e);
                }
            }
        }
        /// <summary>
        /// 获取或设置是否编辑中。
        /// </summary>
        public bool Editing
        {
            get { return _editing; }
            set
            {
                if (_editing != value)
                {
                    _editing = value;
                    OnEditingChanged(EventArgs.Empty);
                }
            }
        }
        /// <summary>
        /// 获取或设置单元格具有焦点。
        /// </summary>
        public bool Focused
        {
            get { return _focused; }
            set 
            {
                if (_focused != value)
                {
                    _focused = value;
                    if (!_focused) Editing = false;
                }
            }
        }
        /// <summary>
        /// 获取或设置文本对齐样式。
        /// </summary>
        public ContentAlignment TextAlign
        {
            get { return _textAlign; }
            set { _textAlign = value; }
        }
        /// <summary>
        /// 获取或设置字体。
        /// </summary>
        public Font Font
        {
            get 
            {
                if (_font == null) _font = SystemFonts.CaptionFont;
                return _font; 
            }
            set { _font = value; }
        }
        /// <summary>
        /// 获取单元格是否合并。
        /// </summary>
        public bool Merged
        {
            get { return _merged; }
            internal set { _merged = value; }
        }
        /// <summary>
        /// 获取或设置左边框样式。
        /// </summary>
        public CellBorderStyle LeftBorderStyle
        {
            get { return _leftBorderStyle; }
            set { _leftBorderStyle = value; }
        }
        /// <summary>
        /// 获取或设置上边框样式。
        /// </summary>
        public CellBorderStyle TopBorderStyle
        {
            get { return _topBorderStyle; }
            set { _topBorderStyle = value; }
        }
        /// <summary>
        /// 获取或设置右边框样式。
        /// </summary>
        public CellBorderStyle RightBorderStyle
        {
            get { return _rightBorderStyle; }
            set { _rightBorderStyle = value; }
        }
        /// <summary>
        /// 获取或设置下边框样式。
        /// </summary>
        public CellBorderStyle BottomBorderStyle
        {
            get { return _bottomBorderStyle; }
            set { _bottomBorderStyle = value; }
        }
        /// <summary>
        /// 获取或设置背景颜色。
        /// </summary>
        public Color BackColor
        {
            get { return _backColor; }
            set { _backColor = value; }
        }
        /// <summary>
        /// 获取或设置前景颜色。
        /// </summary>
        public Color ForeColor
        {
            get { return _foreColor; }
            set { _foreColor = value; }
        }
        /// <summary>
        /// 获取或设置格式化信息。
        /// </summary>
        public string Format
        {
            get { return _format; }
            set
            {
                if (string.Compare(_format, value) != 0)
                {
                     _format = value;
                     OnDisplayText(EventArgs.Empty);
                }
            }
        }
        /// <summary>
        /// 获取单元格是否有边框。
        /// </summary>
        internal protected bool HasBorder
        {
            get
            {
                if (_leftBorderStyle.HasBorder) return true;
                if (_topBorderStyle.HasBorder) return true;
                if (_rightBorderStyle.HasBorder) return true;
                if (_bottomBorderStyle.HasBorder) return true;
                return false;
            }
        }
        /// <summary>
        /// 获取合并后的单元格集合。
        /// </summary>
        internal protected List<Cell> MergedCells
        {
            get { return _mergedCells; }
        }
        /// <summary>
        /// 获取合并后的主单元格。
        /// </summary>
        internal protected Cell MainCell
        {
            get { return _mainCell; }
            set
            {
                if (_mainCell != value)
                {
                    _mainCell = value;
                }
            }
        }

        #endregion

        #region " 友元方法--事件触发 "
        /// <summary>
        /// 触发 DisplayTex 事件。
        /// </summary>
        /// <param name="e">事件参数。</param>
        protected virtual void OnDisplayText(EventArgs e)
        {
            if (DisplayText != null)
            {
                DisplayText(this, e);
            }
            else
            {
                if (!string.IsNullOrEmpty(_format))
                {
                    string format = "{0:" + _format + "}";
                    _text = string.Format(format, _value);
                }
                else
                {
                    _text = string.Format("{0}", _value);
                }
            }
        }
        /// <summary>
        /// 触发 TextChanged 事件。
        /// </summary>
        /// <param name="e">事件参数。</param>
        protected void OnTextChanged(EventArgs e)
        {
            if (TextChanged != null) TextChanged(this, e);
        }
        /// <summary>
        /// 触发 TextChanging 事件。
        /// </summary>
        /// <param name="e">事件参数。</param>
        protected virtual void OnTextChanging(EventArgs e)
        {
            if (TextChanging != null) TextChanging(this, e);
        }
        /// <summary>
        /// 触发 ValueChanged 事件。
        /// </summary>
        /// <param name="e">事件参数。</param>
        protected virtual void OnValueChanged(EventArgs e)
        {
            if (ValueChanged != null) ValueChanged(this, e);
        }
        /// <summary>
        /// 触发 ValueChanging 事件。
        /// </summary>
        /// <param name="e">事件参数。</param>
        protected virtual void OnValueChanging(EventArgs e)
        {
            if (ValueChanging != null) ValueChanging(this, e);
        }
        /// <summary>
        /// 触发 RowIndexChanged 事件。
        /// </summary>
        /// <param name="e">事件参数。</param>
        protected virtual void OnRowIndexChanged(RowIndexChangedEventArgs e)
        {
            if (RowIndexChanged != null) RowIndexChanged(this, e);
        }
        /// <summary>
        /// 触发 ColumnNameChanged 事件。
        /// </summary>
        /// <param name="e">事件参数。</param>
        protected virtual void OnColumnNameChanged(ColumnNameChangedEventArgs e)
        {
            if (ColumnNameChanged != null) ColumnNameChanged(this, e);
        }
        /// <summary>
        /// 触发 EditingChanged 事件。
        /// </summary>
        /// <param name="e">事件参数。</param>
        protected virtual void OnEditingChanged(EventArgs e)
        {
            if (EditingChanged != null) EditingChanged(this, e);
        }
        #endregion

        #region " 绘制 "
        /// <summary>
        /// 绘制单元格。
        /// </summary>
        /// <param name="e">绘图参数。</param>
        public override void Painting(System.Windows.Forms.PaintEventArgs e)
        {
            if (base.Visible)
            {
                DrawingBackground(e);
                DrawingForeground(e);

                base.Painting(e);
            }
        }
        /// <summary>
        /// 绘制背景。
        /// </summary>
        /// <param name="e">绘图参数。</param>
        protected virtual void DrawingBackground(System.Windows.Forms.PaintEventArgs e)
        {
            Color color1 = _backColor;
            Color color2 = _backColor;
            Rectangle rect = Bounds;
            using (Brush brush = new System.Drawing.Drawing2D.LinearGradientBrush(Bounds, color1, color2, 90f))
            {
                e.Graphics.FillRectangle(brush, rect);
            }
            Color borderColor = Color.FromArgb(208, 215, 229);
            if (Focused)
            {
                color1 = Color.FromArgb(155, 234, 236, 245);
                color2 = Color.FromArgb(155, 234, 236, 245);
                borderColor = Color.FromArgb(208, 215, 229);
                using (Brush brush = new System.Drawing.Drawing2D.LinearGradientBrush(Bounds, color1, color2, 90f))
                {
                    e.Graphics.FillRectangle(brush, rect);
                }
            }
            DrawingBorder(e.Graphics, _leftBorderStyle,
                new Point(rect.Left, rect.Top),
                new Point(rect.Left, rect.Bottom));
            DrawingBorder(e.Graphics, _topBorderStyle,
                new Point(rect.Left, rect.Top),
                new Point(rect.Right, rect.Top));
            DrawingBorder(e.Graphics, _rightBorderStyle,
                new Point(rect.Right, rect.Top),
                new Point(rect.Right, rect.Bottom));
            DrawingBorder(e.Graphics, _bottomBorderStyle,
                new Point(rect.Left, rect.Bottom),
                new Point(rect.Right, rect.Bottom));
        }
        /// <summary>
        /// 绘制前景。
        /// </summary>
        /// <param name="e">绘图参数。</param>
        protected virtual void DrawingForeground(System.Windows.Forms.PaintEventArgs e)
        {
            if (_value != null)
            {
                Editor.Painting(e.Graphics);
            }
        }
        /// <summary>
        /// 绘制边框。
        /// </summary>
        /// <param name="g">绘图参数。</param>
        /// <param name="borderStyle">边框样式。</param>
        /// <param name="pt1">开始点。</param>
        /// <param name="pt2">结束点。</param>
        protected virtual void DrawingBorder(Graphics g, CellBorderStyle borderStyle, Point pt1, Point pt2)
        {
            Color borderColor = Color.FromArgb(208, 215, 229);
            using (Pen pen = borderStyle.GetPen(borderColor))
            {
                g.DrawLine(pen, pt1, pt2);
            }
        }
        #endregion

        #region " 事件处理 "
        /// <summary>
        /// 边框样式改变后发生。
        /// </summary>
        /// <param name="sender">事件对象。</param>
        /// <param name="e">事件参数。</param>
        private void _borderStyle_PropertyChanged(object sender, EventArgs e)
        {
            Canvas.Refresh();
        }
        #endregion
    }
}
